import logging
import praw
import os
import signal
import time
from prawcore.exceptions import ServerError, RequestException
from . import WelcomeBot, ModerationHelper, WikiLinker

SUBREDDIT_NAME = 'Piracy'
logger = logging.getLogger('main')


class PrawStreamManager:
    def __init__(self):
        self.time_last_reloaded_streams = time.time()
        self.reload_streams_frequency_secs = 4 * 3600

        # watch for SIGTERM signals (docker stop / docker compose down) to exit gracefully
        self.kill_now = False
        signal.signal(signal.SIGINT, self.exit_gracefully)
        signal.signal(signal.SIGTERM, self.exit_gracefully)

        logger.info('-- Bot starting')

        self.reddit = self._init_reddit()
        self.subreddit = self.reddit.subreddit(SUBREDDIT_NAME)

        self.new_user_handler = WelcomeBot.WelcomeBot(self.reddit)
        self.remover = ModerationHelper.SubmissionRemover(self.reddit)
        self.nuker = ModerationHelper.Nuker(self.reddit)
        self.wiki_linker = WikiLinker.Linker(self.reddit)

        logger.info('-- Loaded handlers')

    def monitor_streams(self):
        comment_stream = self.subreddit.stream.comments(skip_existing=True, pause_after=-1)
        submission_stream = self.subreddit.stream.submissions(skip_existing=True, pause_after=-1)
        inbox_stream = self.reddit.inbox.stream(pause_after=-1)

        logger.info('-- Initializing streams')
        while True:
            if self._is_time_to_reload():
                logger.info('Reloading streams')
                return True
            elif self.kill_now:
                logger.info('Responding to SIGTERM signal')
                return False

            try:
                for submission in submission_stream:
                    if submission is None:
                        break
                    if submission.author is None:
                        continue

                    self.new_user_handler.handle_submission(submission)

                for comment in comment_stream:
                    if comment is None:
                        break
                    if comment.author is None:
                        continue

                    self.new_user_handler.handle_comment(comment)
                    self.wiki_linker.handle_comment(comment)
                    self.remover.handle_comment(comment)
                    self.nuker.handle_comment(comment)

                for message in inbox_stream:
                    if message is None:
                        break
                    if message.author is None:
                        continue

                    self.new_user_handler.handle_message(message)
                    message.mark_read()

            except ServerError as e:
                logger.exception(e)
                time.sleep(45)
                return True
            except RequestException as e:
                logger.exception(e)
                time.sleep(25)
                return True
            except Exception as e:
                logger.error("Undefined exception occurred")
                logger.exception(e)
                return False

    def _is_time_to_reload(self):
        if time.time() - self.time_last_reloaded_streams > self.reload_streams_frequency_secs:
            self.time_last_reloaded_streams = time.time()
            return True
        return False

    def exit_gracefully(self, *args):
        self.kill_now = True

    def _init_reddit(self):
        return praw.Reddit(
            username=os.environ['BOT_USERNAME'],
            password=os.environ['BOT_PASSWORD'],
            client_id=os.environ['CLIENT_ID'],
            client_secret=os.environ['CLIENT_SECRET'],
            user_agent=os.environ['USER_AGENT'],
        )
